Lua源码剖析(二)核心结构体 您所在的位置:网站首页 Rocket Core核心结构剖析 Lua源码剖析(二)核心结构体

Lua源码剖析(二)核心结构体

2024-05-18 18:59| 来源: 网络整理| 查看: 265

一. 前言

  无论是和静态语言交互,还是内部的API,永远少不了lua_State,这就是Lua最核心的栈结构体,也是本文的重点介绍对象。由于该结构体涉及到了众多功能,因此这里不会详细到每一个变量的作用都展开说明,而是站在脚本语言设计和开发者的角度看,设计一个栈结构体,需要哪些部分,留下一个比较系统性的框架概念即可。

二. 核心结构体分析

  写过Lua的demo程序,都不会陌生这个API

1lua_State* luaL_newstate()

  在使用Lua时,首先需要调用该API生成栈,之后再加载文件或是直接填写逻辑。如果说Lua虚拟机执行指令模拟的是CPU的运作,那么Lua栈模拟的就是可执行文件加载在内存的堆栈的操作。在Lua内部参数的传递是通过Lua栈,Lua与C等外部进行交互的时候也是使用的栈。lua_State中保存了大量信息,直接看结构体源码可能就会陷进去了,所以我们可以先分个类。

  设想如果是自己写一个保存脚本执行信息的栈结构体,那可能需要以下几方面内容

全局存储信息,起到类似全局变量之类的效果 栈信息,毫无疑问需要上下限索引、计数等 函数相关,用链表或者其他形式去把所有函数存储起来并且能够获取到 GC相关,用于垃圾回收 函数跟踪调试,给出对外的接口以便于调试代码以及打印情况 异常抛出处理,用于处理异常情况

  而Lua的栈结构体基本也就包括了这几块。首先看看整体的源码,对照刚刚所说的应该就能看懂个大概了,下面会详细就各个方面进行更详细的说明。

12345678910111213141516171819202122232425262728293031// Lua 5.1,本文均为此版本,后续不在标注/*** `per thread' state*/struct lua_State { CommonHeader; lu_byte status; StkId top; /* first free slot in the stack */ StkId base; /* base of current function */ global_State *l_G; CallInfo *ci; /* call info for current function */ const Instruction *savedpc; /* `savedpc' of current function */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ CallInfo *end_ci; /* points after end of ci array*/ CallInfo *base_ci; /* array of CallInfo's */ int stacksize; int size_ci; /* size of array `base_ci' */ unsigned short nCcalls; /* number of nested C calls */ lu_byte hookmask; lu_byte allowhook; int basehookcount; int hookcount; lua_Hook hook; TValue l_gt; /* table of globals */ TValue env; /* temporary place for environments */ GCObject *openupval; /* list of open upvalues in this stack */ GCObject *gclist; struct lua_longjmp *errorJmp; /* current error recover point */ ptrdiff_t errfunc; /* current error handling function (stack index) */}; 2.1 全局信息

  全局信息成员变量如下,TValue在数值一讲中详谈。

12345struct lua_State { global_State *l_G; TValue l_gt; /* table of globals */ TValue env; /* temporary place for environments */ }

  对应结构体global_State主要包含几方面的全局内容

字符串的哈希表(下一讲中会详细说明) 原表、上值等 内存分配函数 GC相关的众多链表及相应变量(后续在GC一文详细展开说明) 全局统计信息:总内存、正在使用的内存估算

  源码如下,可以对照着过一遍,有个大致印象就好,后面会用到的地方会具体说明。

123456789101112131415161718192021222324252627282930/*** `global state', shared by all threads of this state*/typedef struct global_State { stringtable strt; /* hash table for strings */ lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to `frealloc' */ lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ int sweepstrgc; /* position of sweep in `strt' */ GCObject *rootgc; /* list of all collectable objects */ GCObject **sweepgc; /* position of sweep in `rootgc' */ GCObject *gray; /* list of gray objects */ GCObject *grayagain; /* list of objects to be traversed atomically */ GCObject *weak; /* list of weak tables (to be cleared) */ GCObject *tmudata; /* last element of list of userdata to be GC */ Mbuffer buff; /* temporary buffer for string concatentation */ lu_mem GCthreshold; lu_mem totalbytes; /* number of bytes currently allocated */ lu_mem estimate; /* an estimate of number of bytes actually in use */ lu_mem gcdept; /* how much GC is `behind schedule' */ int gcpause; /* size of pause between successive GCs */ int gcstepmul; /* GC `granularity' */ lua_CFunction panic; /* to be called in unprotected errors */ TValue l_registry; struct lua_State *mainthread; UpVal uvhead; /* head of double-linked list of all open upvalues */ struct Table *mt[NUM_TAGS]; /* metatables for basic types */ TString *tmname[TM_N]; /* array with tag-method names */} global_State; 2.2 栈信息

  既然是Lua栈,那么自然需要保存栈底和栈顶,以及入栈内容的相关信息,相关源码如下。这里注释都很清楚,没有什么难懂的地方,就是通过几个索引位置让各种栈操作可以方便的执行。

123456789typedef TValue *StkId; /* index to stack elements */struct lua_State { StkId top; /* first free slot in the stack */ StkId base; /* base of current function */ StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ int stacksize;} 2.3 函数

  多个函数的入栈和调用等操作当然都需要保存在栈内,所以需要函数相关的一系列成员变量

12345678struct lua_State { CallInfo *ci; /* call info for current function */ const Instruction *savedpc; /* `savedpc' of current function */ CallInfo* end_ci; /* points after end of ci array*/ CallInfo* base_ci; /* array of CallInfo's */ int size_ci; /* size of array `base_ci' */ unsigned short nCcalls; /* number of nested C calls */ }

  lua_State中的CallInfo保存当前调用函数的信息,也提供了一系列指针方便索引栈、函数顶、其他函数。定义如下:

1234567891011/*** informations about a call*/typedef struct CallInfo { StkId base; /* base for this function */ StkId func; /* function index in the stack */ StkId top; /* top for this function */ const Instruction* savedpc; int nresults; /* expected number of results from this function */ int tailcalls; /* number of tail calls lost under this entry */} CallInfo;

  lua_State和CallInfo初始化主要在stack_init()函数中执行。

1234567891011121314151617181920static void stack_init(lua_State *L1, lua_State *L){ int i; CallInfo *ci; /* initialize stack array */ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); L1->stacksize = BASIC_STACK_SIZE; for (i = 0; i < BASIC_STACK_SIZE; i++) setnilvalue(L1->stack + i); /* erase new stack */ L1->top = L1->stack; L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; /* initialize first ci */ ci = &L1->base_ci; ci->next = ci->previous = NULL; ci->callstatus = 0; ci->func = L1->top; setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ ci->top = L1->top + LUA_MINSTACK; L1->ci = ci;} 2.4 GC

  GC的主要相关变量在global_State中定义,但是除此之外仍有两个特殊变量

1234struct lua_State { GCObject* openupval; /* list of open upvalues in this stack */ GCObject* gclist;}

  这里之所以会存在一个gclist,是因为lua_State本身也是一个可以GC的对象,为了方便GC统一处理因此做了这种统一化的存在,而不适合放在global_State之中。openupval的话,是因为专属于这个栈,因此必须放在这儿。关于上值,在后续基础数据类型中会有详细说明。

2.5 Hook

  对于脚本语言,我们也希望能够提供一种跟踪、调试的方法,对于Lua来说,其实现就是Hook系列。该部分内容比较有趣,后续会单独展开详谈。

1234567struct lua_State { lu_byte hookmask; lu_byte allowhook; int basehookcount; int hookcount; lua_Hook hook;} 三. 总结

  本文对lua_State进行了概要介绍,希望是有一个提纲式的了解,掌握栈的基础构造,细节内容后面慢慢填充即可。

参考文献

Lua-Source-Internal

《A No Frills Introduction to Lua 5.1 VM Instructions》

http://lua-users.org/wiki/LuaSource

《The Implementation of Lua 5.0》



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有